import tornado.ioloop
import tornado.web
from urllib.parse import unquote
import requests
import re,os,sys
import json,uuid,time

directionip="http://192.168.1.83"
directionport="8887"

def RemoveModules(moduleName):
    if type(moduleName) != type("") or moduleName == "":
        return
    if moduleName in sys.modules:
        sys.modules.pop(moduleName)
    if moduleName in globals():
        globals().pop(moduleName)
    if moduleName in locals():
        locals().pop(moduleName)

class ProxyHandle(tornado.web.RequestHandler):
    def get(self):
        URL = self._parseURL()
        try:
            with requests.get(URL, timeout=30) as response:
                if response.ok:
                    if response.headers and len(response.headers) != 0:
                        for key, val in response.headers.items():
                            self.set_header(key, val)
                    self.write (response.content)
                else:
                    self.write ("error:%s" % "服务请求错误")
        except:
            self.write_error(500)

    def post(self):
        URL = self._parseURL()
        urlParam = bytes.decode(self.request.body)
        urlParam = urlParam.encode('utf-8')
        try:
            response = requests.post(URL, data = urlParam, timeout=30)
            if response.ok:
                if response.headers and len(response.headers) != 0:
                    for key, val in response.headers.items():
                        self.set_header(key, val)
                self.write (response.content)
            else:
                self.write ("error:%s" % "服务请求错误")
            response.close()
        except:
            self.write_error(500)

    def _parseURL(self):
        global directionip, directionport
        uri = self.request.uri
        uri = str(unquote(uri, 'utf-8'))
        uri = uri.replace(re.match('/proxy/?', uri).group(),"")

        return "%s:%s/%s" % (directionip, directionport, uri)

    def write_error(self, status_code, **kwargs):
        msg = ''
        if kwargs and len(kwargs) != 0:
            for key, val in kwargs.items():
                if not msg:
                    msg = '_'
                else:
                    msg = msg + ','
                msg = msg + ('%s:%s' % (key, val))
        self.write('Detect Error %s%s' % (status_code, msg))

class ProxyRedirHandle(tornado.web.RequestHandler):
    def get(self):
        try:
            uri = self.request.uri
            uri = str(unquote(uri, 'utf-8'))
            strArray = uri.split('?')
            self._handle (strArray[1])
        except:
            pass
        finally:
            self._return()

    def post(self):
        try:
            urlParam = bytes.decode(self.request.body)
            self._handle(urlParam)
        finally:
            self._return()

    def _handle(self, req):
        global directionip, directionport

        if req:
            array = req.split('&')
            if array and len(array) != 0:
                for a in array:
                    try:
                        aret = a.split('=')
                        if aret[0] == 'ip':
                            directionip = aret[1]
                        elif aret[0] == 'port':
                            directionport = aret[1]
                    except:
                        pass

    def _return(self):
        global directionip, directionport
        returnString = 'ip:%s,port:%s' % (directionip, directionport)
        self.write(returnString)

# 重新训练
class RetrainHandle(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        uri = self.request.uri
        uri = str(unquote(uri, "utf-8"))
        self.handle(lambda: uri.split("?")[1])
    def post(self, *args, **kwargs):
        self.handle(lambda: bytes.decode(self.request.body))

    def handle(self, toparam):
        msg = "空闲中"
        try:
            param = toparam()
            msg = {
                "status": self.status,
                "all": self.train
            }.get(param, self.default) ()
        except Exception as e:
            msg = "无效参数:" + str(param) + "=>" + str(e)
        finally:
            self.write(msg)

    def train(self):
        if self.IsTraining():
            return self.status()
        else:
            code = os.system('bash `locate /RMatch/exec.sh -l 1` '+ time.strftime('%H:%M:%S',time.localtime(time.time())) +' &')
            return "success" if code == 0 else "failure"

    def IsTraining(self):
        try:
            results = [x for x in [[temp.strip() for temp in item.strip().split(' ') if temp.strip() != ""] for item in os.popen("ps -ef|grep HttpService.py").read().split('\n') if item.strip() != ''] if x[7] == 'python3']
            return len(results) > 1
        except:
            return False

    def status(self):
        if self.IsTraining ():
            return '训练中'
        else:
            try:
                results = [x for x in [[temp.strip() for temp in item.strip().split(' ') if temp.strip() != ""] for item in os.popen("ps -ef|grep HttpService.py").read().split('\n') if item.strip() != ''] if x[7] == 'python3']
                result = results[len(results)-1]
                return '空闲中  ' + result[len(result)-1]
            except:
                return '空闲中'

    def default(self):
        return "无效参数"

class FixedCADHandle(tornado.web.RequestHandler):
    def post(self, *args, **kwargs):
        content = bytes.decode(self.request.body)
        def FixedCAD(text):
            if text is None or text == "":
                return text
            obj = json.loads(text)
            if 'rooms' not in obj or len(obj['rooms']) == 0:
                return text
            for room in obj['rooms']:
                uid = str(uuid.uuid1())
                uid = ''.join(uid.split('-'))
                room['name'] = uid
            return json.dumps(obj)
        try:
            self.write(FixedCAD(content))
        except:
            self.write(content)

class KillMatchHandle(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        self.handle()
    def post(self, *args, **kwargs):
        self.handle()
    def handle(self):
        modules = 'TimingTask'
        __import__(modules)
        RemoveModules (modules)

if __name__ == "__main__":
    app = tornado.web.Application(
        [
            (r"/proxy.*", ProxyHandle),
            (r"/redir", ProxyRedirHandle),
            (r"/retrain", RetrainHandle),
            (r"/fixecad", FixedCADHandle),
            (r"/killMatch", KillMatchHandle)
        ]
    )
    app.listen(8889)
    print('服务启动完毕')
    tornado.ioloop.IOLoop.current().start()